﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Database;
using Entity;

namespace Business
{
    public enum AgrupamentoPonto
	{
        Diario, Semanal, Mensal
	}

    public class PontoBO
    {
        public static List<PontoDiarioEntity> ObterListaPontoDiario(int mes, int ano)
        {
            DateTime dtFiltroIni = new DateTime(ano, mes, 1);
            DateTime dtFiltroFim = new DateTime(ano, mes + 1, 1);

            var query = from lancamento in BaseBO.TBLancamento
                        where lancamento.Entrada.Date >= dtFiltroIni && lancamento.Entrada.Date < dtFiltroFim
                        group lancamento by lancamento.Entrada.Date into lancamentoGroup
                        select new PontoDiarioEntity
                        {
                            Horas = lancamentoGroup.Sum(lancamento => (lancamento.Saida.Subtract(lancamento.Entrada).TotalHours)),
                            Dia = lancamentoGroup.Key.Date
                        };

            return query.ToList();
        }

        public static List<PontoSemanalEntity> ObterListaPontoSemanal(int mes, int ano)
        {
            List<PontoDiarioEntity> lstPontoDiario = ObterListaPontoDiario(mes, ano);

            List<PontoSemanalEntity> lstPontoSemanal = ComputarSemanas(mes, ano);

            foreach (PontoSemanalEntity pontoSemanal in lstPontoSemanal)
            {
                var query = from pd in lstPontoDiario
                            where pd.Dia >= pontoSemanal.DtIni && pd.Dia <= pontoSemanal.DtFim
                            group pd by pd.Dia into pdGroup
                            select new
                            {
                                QtDias = pdGroup.Count(),
                                QtHoras = pdGroup.Sum(pd => pd.Horas)
                            };

                if (query.Count() > 0)
                {
                    var rs = query.First();

                    pontoSemanal.QtDias = rs.QtDias;
                    pontoSemanal.QtHoras = rs.QtHoras;
                }
                else
                {
                    pontoSemanal.QtDias = 0;
                    pontoSemanal.QtHoras = 0;
                }
            }

            return lstPontoSemanal;
        }

        public static PontoMensalEntity ObterPontoMensal(int mes, int ano)
        {
            List<PontoDiarioEntity> lstPontoDiario = ObterListaPontoDiario(mes, ano);

            PontoMensalEntity pontoMensal = new PontoMensalEntity();

            pontoMensal.Mes = mes;

            var query = from pd in lstPontoDiario
                        select pd.Horas;

            pontoMensal.QtHoras = query.Sum();

            return pontoMensal;
        }

        private static List<PontoSemanalEntity> ComputarSemanas(int mes, int ano)
        {
            List<PontoSemanalEntity> lstPontoSemanal = new List<PontoSemanalEntity>();

            int dia = 1;

            DateTime dataAux = new DateTime(ano, mes, dia);

            bool sair = false;
            while (!sair)
            {
                PontoSemanalEntity ponto = new PontoSemanalEntity();
                ponto.DtIni = new DateTime(ano, mes, dia);

                int diasRestantesSemana = 7 - (int)ponto.DtIni.DayOfWeek;
                
                //Se passou do último dia do mês
                if (ponto.DtIni.AddDays(diasRestantesSemana).Month > mes)
                    ponto.DtFim = new DateTime(ano, mes, DateTime.DaysInMonth(ano, mes));
                else
                    ponto.DtFim = ponto.DtIni.AddDays(diasRestantesSemana);

                lstPontoSemanal.Add(ponto);

                //Se o dia seguinte ao último dia computado é no mês seguinte, sai
                if (ponto.DtFim.AddDays(1).Month > mes)
                    sair = true;
                else
                    dia = ponto.DtFim.AddDays(1).Day;
            }

            return lstPontoSemanal;
        }
    }
}
